package com.ssq.redballs;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ssq.common.Utils;

public class PrevIssueArithmetic {
	private int num=21;//算法格式
	private int buleBall;
	private int[] redBalls;
	private String issueNum;
	public static Map<Integer, Integer> statMap = new HashMap<Integer, Integer>(0);
	
	
	public PrevIssueArithmetic(){
		buleBall = Utils.getPrevBuleBall();
		redBalls = Utils.getPrevRedBalls();
	}
	
	public PrevIssueArithmetic(String issueNum){
		this.issueNum = issueNum;
		buleBall = Utils.getBuleBall(issueNum);
		redBalls = Utils.getRedBalls(issueNum);
	}
	/**
	 * 根据不可能出的数计算出可能出的数
	 * @param notSelect
	 * @return
	 */
	public int[] generateSelect() {
		List<Integer> selectArray = new ArrayList<Integer>();
		int[] notSelect = generateNotSelectRedball();
		for (int i = 1; i <= 33; i++) {
			boolean flag =false;
			for (int j : notSelect) {
				if (i == j) 
					flag = true;
			}
			if (!flag) {
				selectArray.add(i);
			}
		}
		//info("出现的数",selectArray);		
		return Utils.tranferToArray(selectArray);
	}
	
	/**
	 * 获取不可能出现的数的算法
	 * @return
	 */
	private int[] generateNotSelectRedball(){
		List<Integer> notSelectArray = new ArrayList<Integer>();
		for (int i = 0; i < num; i++) {
			int returnNum = prevArithmetic(i+1);
			notSelectArray = clearRepeat(returnNum,notSelectArray);
			//-- 统计方法
			statistic(returnNum, i+1);		
		}
		//info("不出现的数",notSelectArray);
		return Utils.tranferToArray(notSelectArray);
	}


	/**
	 * 过滤重复数字
	 * @param i 
	 * @param notSelectArray 
	 */
	private List<Integer> clearRepeat(int num, List<Integer> notSelectArray) {
		boolean flag = false;
		for (Integer arrayNum : notSelectArray) {
			if (num == arrayNum) {
				flag =true;
			}
		}
		if (!flag) 
			notSelectArray.add(num);
		return notSelectArray;
	}
	
	/**
	 * 输出控制台信息
	 */
	private void info(String prompt,List<Integer> notSelectArray) {
		System.out.print(prompt+">> ");
		for (Integer notSel: notSelectArray) {
			System.out.print(" "+notSel);
		}
		System.out.print("\n");
	}
	
	/*
	 * 双色球杀红码公式汇总
	 */
	public int prevArithmetic(int index){
		switch (index) {
			case 1://-- 1当期开奖号码大小顺序第一位与第六位的差，计算的结果在下一期有可能不出。
				int reNum = prevArithmetic_01();
				String issueNum = null;

				//isExist(reNum, issueNum);
				return reNum;
				
			case 2://-- 2 当期开奖号码大小顺序第二位与第三位的差，计算的结果在下一期有可能不出。
				return prevArithmetic_02();
				
			case 3://-- 3当期开奖号码大小顺序第二位与第五位的差，计算的结果在下一期有可能不出。
				return prevArithmetic_03();
				
			case 4://-- 4当期开奖号码大小顺序第一位乘4再减掉2，计算的结果在下一期有可能不出。
				return prevArithmetic_04();
				
			case 5://-- 5当期开奖号码大小顺序第一位加当期开奖的兰号，计算的结果再乘3后，所得的号码在下一期有可能不出。
				return prevArithmetic_05();
				
			case 6://-- 6当期开奖号码大小顺序第一位加09，计算的结果在下一期有可能不出。
				return prevArithmetic_06();
				
			case 7://-- 7当期开奖号码大小顺序第二位加05，计算的结果在下一期有可能不出。
				return prevArithmetic_07();
				
			case 8://-- 8当期开奖号码大小顺序第三位加04，计算的结果在下一期有可能不出。
				return prevArithmetic_08();
				
			case 9://-- 9当期开奖号码大小顺序第三位加07，计算的结果在下一期有可能不出。
				return prevArithmetic_09();
				
			case 10://-- 10当期开奖号码大小顺序第六位加04，计算的结果在下一期有可能不出。
				return prevArithmetic_10();
				
			case 11://-- 11当期开奖号码大小顺序第四位与第五位的差，加当期的兰号，再加01，计算的结果在下一期有可能不出。
				return prevArithmetic_11();
				
			case 12://-- 12当期开奖的兰号，加当期开奖号码大小顺序第一位，计算的结果在下一期有可能不出。（备注：如遇兰号重复，重复的兰号再另外减去01）
				return prevArithmetic_12();
			case 13://-- 13当期开奖的兰号，加当期开奖号码大小顺序第二位，再减去01，计算的结果在下一期有可能不出。
				return prevArithmetic_13();
			case 14://-- 14当期开奖的兰号，减当期开奖号码大小顺序第四位，再加上01，计算的结果在下一期有可能不出。
				return prevArithmetic_14();
			case 15://-- 15当期开奖的兰号，减当期开奖号码大小顺序第五位，计算的结果在下一期有可能不出。
				return prevArithmetic_15();
			case 16://-- 16 当期开奖的兰号，乘当期开奖号码大小顺序第一位，计算的结果在下一期有可能不出。
				return prevArithmetic_16();
			case 17://-- 17当期开奖的兰号，加+07，计算的结果在下一期有可能不出。
				return prevArithmetic_17();
			case 18://-- 18当期开奖的兰号，加+09，计算的结果在下一期有可能不出。
				return prevArithmetic_18();
			case 19://-- 19当期开奖的兰号，乘05加+02，计算的结果在下一期有可能不出。
				return prevArithmetic_19();
			case 20://-- 20当期开奖的兰号，如为偶数时，乘上2，再加02，计算的结果在下一期有可能不出，到目前为止，此条件无错误。
				if (this.buleBall%2==0) {
					return prevArithmetic_20();
				}
			case 21://-- 21当期开奖的兰号，如为奇数时，乘上5，再加+02，计算的结果在下一期有可能不出。
				if (this.buleBall%2==1) {
					return prevArithmetic_21();
				}
				
			default: 
				break;
		}
		
		return 0;
	}	
	

	/**
	 * 统计
	 * @param reNum
	 * @param j
	 */
	private void statistic(int reNum, int j) {

		//--下期 号码
		int[] nextIssue = Utils.getRedBalls(Utils.plus(this.issueNum,1));
		
		boolean flag  = true;
		for (int i = 0; i < nextIssue.length; i++) {
			if (reNum == nextIssue[i]) {//-- 杀准红球不出，算法准确记录
				flag = false;
			}
		}
		if (flag) {
			if (statMap.get(j)!=null) {
				statMap.put(j, 1+statMap.get(j));
			}else {
				statMap.put(j, 1);
			}
		}
		
	}


	/**
	 *  1当期开奖号码大小顺序第一位与第六位的差，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_01(){
		return minusAbs(1, 6);
	}
	
	/**
	 * 2 当期开奖号码大小顺序第二位与第三位的差，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_02(){
		return minusAbs(2, 3);
	}
	
	/**
	 * 3当期开奖号码大小顺序第二位与第五位的差，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_03(){
		return minusAbs(2, 5);
	}
	
	/**
	 * 4当期开奖号码大小顺序第一位乘4再减掉2，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_04(){
		return redBalls[0]*4-2;
	}
	
	/**
	 * 5当期开奖号码大小顺序第一位加当期开奖的兰号，计算的结果再乘3后，所得的号码在下一期有可能不出。
	 */
	public int prevArithmetic_05(){
		return (redBalls[0]+this.buleBall)*3;
	}

	/**
	 *  6当期开奖号码大小顺序第一位加09，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_06(){
		return redBalls[0]+9;
	}
	
	/**
	 * 7当期开奖号码大小顺序第二位加05，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_07(){
		return redBalls[1]+5;
	}
	
	/**
	 *  8当期开奖号码大小顺序第三位加04，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_08(){
		return redBalls[2]+4;
	}
	
	/**
	 * 9当期开奖号码大小顺序第三位加07，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_09(){
		return redBalls[2]+7;
	}
	
	/**
	 * 10当期开奖号码大小顺序第六位加04，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_10(){
		return redBalls[5]+4;
	}

	/**
	 * 11当期开奖号码大小顺序第四位与第五位的差，加当期的兰号，再加01，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_11(){
		return minusAbs(4, 5)+this.buleBall+1;
	}
	
	/**
	 * 12当期开奖的兰号，加当期开奖号码大小顺序第一位，计算的结果在下一期有可能不出。（备注：如遇兰号重复，重复的兰号再另外减去01）
	 */
	public int prevArithmetic_12(){
		return (this.buleBall+redBalls[0]);
	}
	
	/**
	 * 13当期开奖的兰号，加当期开奖号码大小顺序第二位，再减去01，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_13(){
		return (this.buleBall+redBalls[1]-1);
	}
	
	/**
	 * 14当期开奖的兰号，减当期开奖号码大小顺序第四位，再加上01，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_14(){
		return (this.buleBall+redBalls[3]+1);
	}
	
	/**
	 * 15当期开奖的兰号，减当期开奖号码大小顺序第五位，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_15(){
		return Math.abs(this.buleBall-redBalls[4]);
	}
	
	/**
	 *16 当期开奖的兰号，乘当期开奖号码大小顺序第一位，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_16(){
		return (this.buleBall*redBalls[0]);
	}
	
	/**
	 * 17当期开奖的兰号，加+07，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_17(){
		return (this.buleBall+7);
	}
	
	/**
	 * 18当期开奖的兰号，加+09，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_18(){
		return (this.buleBall+9);
	}
	
	/**
	 * 19当期开奖的兰号，乘05加+02，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_19(){
		return (this.buleBall*5+2);
	}
	
	/**
	 * 20当期开奖的兰号，如为偶数时，乘上2，再加02，计算的结果在下一期有可能不出，到目前为止，此条件无错误。
	 */
	public int prevArithmetic_20(){
		return this.buleBall*2+2;
	}
	
	/**
	 * 21当期开奖的兰号，如为奇数时，乘上5，再加+02，计算的结果在下一期有可能不出。
	 */
	public int prevArithmetic_21(){
		return (this.buleBall*5+2);
	}
	
	
	/********************************************************************
	 ********************************************************************
	 *******************************************************************/
	
	/**
	 * 两数相减的绝对值
	 * @param num1
	 * @param num2
	 * @return
	 */
	private int minusAbs(int num1, int num2) {
		return Math.abs(redBalls[num1-1]-redBalls[num2-1]);
	}
	
	/**
	 * 两数相加
	 * @param num1
	 * @param num2
	 * @return int
	 */
	private int plus(int num1, int num2) {
		return redBalls[num1-1]+redBalls[num2-1];
	}
	
	/**
	 * 指定号码是否在下期的
	 */
	
	private boolean isExist(int num, String issueNum){
		boolean flag = false;
		int[] numArray = Utils.getRedBalls(issueNum);
		for (int i: numArray) {
			if(i == num) 
				flag = true;
		}
		return flag;
	}


	public void setIssueNum(String issueNum) {
		this.issueNum = issueNum;
	}
		
	
}
